﻿$(document).ready (function () {	// When the DOM is ready
	$('head').append ('<link rel="stylesheet" href="css/folders.css"/>');		// Add the CSS for the file dialog
});

/**
 * All functionality for the file dialog is held in this class
 */
function Folders () {
	this.current = -1;			// Currently selected folder
	this.folderSelected = null;	// Method to call when a folder is selected
	this.fileClick = null;		// Method to call when a file is selected
}

var folders = new Folders ();	// Create an object of the Folders class

/**
 * This function is called when a file is dropped on the file dialog.
 * Ie. this is where Drag&Drop file upload is handled.
 */
Folders.prototype.upload = function (event) {
	if (folders.current==-1) {				// No upload to root folder, a folder must be selected first
		alert ('Velg en katalog først.');
		event.preventDefault();			// We do not want the default behaviour
		return;
	}
	if (event.dataTransfer.files.length==1) { 	// We only accept single file uploads
		var progressBar = document.querySelector('.progress-bar');	// Get a reference to the file upload progress bar
		// Initialize the progress bar to 0%:
		$('.progress-bar').attr("aria-valuenow", "0");
		$('.progress-bar').attr("style", "width: 0%");
		$('.progress-bar').text("0% Complete");
		$('#progressDiv').show();					// Show the file upload progress and information div
		var file = event.dataTransfer.files[0]; // Get the file to upload

		var xhr = new XMLHttpRequest();			// Create a new XMLHttpRequest object
		xhr.open('POST', 'includes/functions/DnDUpload.php', true);	// What script is used to receive the uploaded file
		
		// Set header information for the folder, filename and other data
		// This is the only way to transfer this information when uploading in this way
		xhr.setRequestHeader('folder', folders.current);
		xhr.setRequestHeader('filename', file.name);
		xhr.setRequestHeader('size', file.size);
		xhr.setRequestHeader('type', file.type);
		xhr.onload = function(e) { 	// When the request is completed 
			$('#progressDiv').hide(); 	// Hide the progress display
			folders.showFiles();	// Display all files, including the newly uploaded file
		};

		xhr.upload.onprogress = function(e) {					// When a chunk of data has been uploaded
			if (e.lengthComputable) { 							// If the progress can be found
				var val = (e.loaded / e.total) * 100;	// Update the progress bar:
				$('.progress-bar').attr("aria-valuenow", val);
				$('.progress-bar').attr("style", "width: "+val+"%");
				$('.progress-bar').text(val+"% Complete");
			}
		};
		xhr.send(file);				// Send the file from the browser to the receiving script
	} else if (event.dataTransfer.files.lengthevent.dataTransfer.files.length>1)	// Attempted to upload more than one file
		alert ('Systemet håndterer kun opplasting av en fil om gangen.');			// Give an error message
	event.preventDefault();			// We do not want the default behaviour
	return false;
}

/**
 * Initialization function for the folders class, used to load the initial set of folders into the view.
 */
Folders.prototype.init = function () {
	$.ajax ({
		url: 'includes/functions/fetchFolders.php',		// Use this script to get a list of folders to display
		data: {'id': -1},				// Get all folders that are children of the root folder
		type: 'post',
		success: function (data) {		// When data is returned
			$('#folders').html ('<ul class="folders"></ul>');	// Add an unnumbered list to the folders div tag
			for (var i=0; i<data.length; i++) {					// Loop through all returned data and append each folder to the newly create unnumbered list
				$('#folders .folders').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
				$('#folders .folders').last().loaded = false;	// Indicate that the content of this folder has never been loaded
			}
		}
	});
}

/**
 * Method called to open/close a subfolder view
 * When a folder that has not been loaded is opened for the first time
 * the content of that folder is loaded through an Ajax call.
 */
Folders.prototype.openClose = function (id) {	// id is the id of the folder to be opened/closed
	if (this.current>0)		// If a folder is currently selected
		$('#folder_'+this.current).toggleClass ('selected');	// remove the selection from the currently selected item
	this.current = id;		// Update the currently selected folder to the newly selected folder
	$('#folder_'+this.current).toggleClass ('selected');		// Then add the selection class to this folder
	
	if ($('#folder_'+id)[0].loaded) {			// If the folder to be opened is already loaded
		$('#folder_'+id+' ul').toggle ();		// Toggle the status of the ul tag below this folder (if shown - hide, if hidden - show)
		if ($('#folder_'+id)[0].hasSubFolders) {		// If the selected folder has any subfolders, toggle the folder open/closed classes
			$('#folder_'+id).toggleClass ('opened');
			$('#folder_'+id).toggleClass ('closed');
		}
	} else {									// Currently selected folder has not been loaded
		$('#folder_'+id)[0].loaded = true;	// Change the flag, so that on the next switch we say we are loaded
		$('#folder_'+id).append ('<ul class="folders"></ul>');	// Append the unnumbered list holding data about the subfolders
		$.ajax ({								// Use Ajax to load the data about subfolders
			url: 'includes/functions/fetchFolders.php',			// Script used to return data about subfolders
			data: {'id': id},					// Find folders with this folder as parent
			type: 'post',
			success: function (data) {			// When the data is returned
				if (data.length>0) {			// If folder contains subfolders
					$('#folder_'+id)[0].hasSubFolders = true;		// Set a flag indicating this folders has subfolders
					$('#folder_'+id).toggleClass ('opened');		// Also set the icon of the folder to represent an opened folder
					$('#folder_'+id+' nobr #foldericon').toggleClass ('glyphicon glyphicon-folder-open');
				}	else						// No subfolders
					$('#folder_'+id)[0].hasSubFolders = false;	// Set a flag indicating no subfolders for this folder
				for (var i=0; i<data.length; i++) {		// Loop through the data for all the subfolders
					// Add a list item for each subfolder
					$('#folder_'+id+' ul').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
					$('#folder_'+id+' ul li').last().loaded = false;	// For each subfolder, indicate that no data has been loaded for this subfolder
				}
			}
		});
	}
	// Now the folder hierarcy is updated
	folders.showFiles ();		// Show the files of the newly selected folder
}

/**
 * This function is used to create a new subfolder with the given name
 *
 * @param name the name of the subfolder to create
 */
Folders.prototype.createNewFolder = function(name) {
	$.ajax ({
		url: 'includes/functions/createNewFolder.php',		// Script used to save the new folder in the database
		data: {'name': name, 'parentId': folders.current},	// Need to send the name of the folder to create and the id of the parent folder
		type: 'post',
		success: function (data) {		// When the folder is created
			if (data.error) {			// If an error occured
				alert (data.error);		// Show the error message
				return;					// Return
			}
			if (folders.current==-1) {	// If we have created a folder under the root folder
				$('#folders').html ('<ul class="folders"></ul>');	// Empty the list of folders beneath the root folder
				for (var i=0; i<data.length; i++) {					// The same data is returned as when we display the folders in the first place
					// Append each subfolders as a li item
					$('#folders .folders').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
					$('#folders .folders').last().loaded = false;	// Indicate that no data about the subfolder has been loaded
				}
			} else {					// The folder was created under a non root folder
				var newSelected = 0;	// used to get the id of the newly created folder
				$('#folder_'+folders.current).toggleClass ('selected');	// Set the folder that we created a new folder under to be unselected
				$('#folder_'+folders.current+' ul').empty ();				// Remove everything under the folder in which we created a new folder
				$('#folder_'+folders.current+' ul').show ();				// Make sure that the content of the folder in which we created a new folder is displayed
				$('#folder_'+folders.current).hasSubFolders = true;		// The folder in which we created a folder certainly has children
				$('#folder_'+folders.current).removeClass ('opened');		// Set the folder in which we create a folder to be unopened
				for (var i=0; i<data.length; i++) {		// Add back in all children of the folder where we created a new folder
					$('#folder_'+folders.current+' ul').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
					$('#folder_'+folders.current+' ul li').last().loaded = false;	// Set all subfolders to be not loaded
					if (data[i].name==name)				// If this is the newly created subfolder
						newSelected = data[i].id;		// Store its id
				}
				folders.current = newSelected;			// The currently selected folder is the newly created folder
				$('#folder_1_'+folders.current).toggleClass ('selected');	// Set the newly created folder to be the selected folder
			}
			
			// Now the folder hierarcy is updated
			folders.showFiles ();		// Show the files (empty list since the folder is just created) of the selected folder
		}
	});
}

/**
 * This function is called to remove the currently selected folder.
 */
Folders.prototype.removeFolder = function() {
	if (this.current==-1)		// We can't remove the root folder
		return;					// Just return
	$.ajax ({
		url: 'includes/functions/removeFolder.php',	// Script used to remove a folder
		data: {'id': folders.current},	// The id of the folder to remove
		type: 'post',
		success: function (data) {		// When the script returns
			if (data.error) {			// If an error occured
				alert (data.error);		// Display the error message
				return;
			}
			folders.current = data[0].id; 	// Since a folder was remove, the id of the parent folder is returned in data[0].id
			if (folders.current==-1) {		// A folder with the root folder as parent was removed
				$('#folders').html ('<ul class="folders"></ul>');	// Clear all folders under the root folder
				for (var i=1; i<data.length; i++) {					// Then add back the folders remaining under the root node
					$('#folders .folders').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
					$('#folders .folders').last().loaded = false;	// Set the loaded flag to false for all subfolders
				}
			} else {				// A folder under a non root folder was deleted
				$('#folder_'+folders.current+' ul').empty ();				// Clear the subfolders of the parent folder for the deleted folder
				$('#folder_'+folders.current).hasSubFolders = false;		// We might not have any subfolders
				$('#folder_'+folders.current).removeClass ('opened');		
				$('#folder_'+folders.current).removeClass ('closed');
				if (data.length>1)				// If we has subfolders, indicate that this folder has child folders
					$('#folder_'+folders.current).toggleClass ('opened');
				for (var i=1; i<data.length; i++) {		// Loop through all remaining subfolders
					$('#folder_'+folders.current+' ul').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="foldericon">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
					$('#folder_'+folders.current+' ul li').last().loaded = false;	// Indicate that no data has been loaded for this subfolder
					$('#folder_'+folders.current).hasSubFolders = true;		// The parent folder has children
				}
				if ($('#folder_'+folders.current).hasSubFolders)		// If we have subfolders
					$('#folder_'+folders.current).toggleClass ('opened');	// Toggle the opened class
				$('#folder_'+folders.current).toggleClass ('selected');	// Set this folder containing the folder we deleted as the selected folder
			}
			
			// The folder hierarcy is updated
			folders.showFiles ();		// Show all files of selected folder
		}
	});
}

/**
 * Function used to rename folder.
 *
 * @param name the new name of the folder
 */
Folders.prototype.renameFolder = function(name) {
	if (this.current==-1)		// If no folder is selected
		return;					// Do nothing
	$.ajax ({	
		url: 'includes/functions/renameFolder.php',		// Use this script to rename the folder
		data: {'name': name, 'id': folders.current},	// Need to provide the new name and the id of the folder to rename
		type: 'post',
		success: function (data) {		// When the script returns
			if (data.error) {			// An error occured
				alert (data.error);		// Display the error message
				return;
			}
			var renamedFolder = folders.current;	
			folders.current = data[0].id; 	// We get the id of the folder containing the rename folder in data[0].id
			$('#folder_'+folders.current+' ul').empty ();	// Clear all folders of the parent folder of the renamed folder
			for (var i=1; i<data.length; i++) {				// Loop through all folders of the parent folder
				// Add the children back in
				$('#folder_'+folders.current+' ul').append ('<li id="folder_'+data[i].id+'"><nobr><span class="openClosed">&nbsp;</span><span class="glyphicon glyphicon-folder-close">&nbsp;</span><a href="javascript:folders.openClose('+data[i].id+');">'+data[i].name+'</a></nobr></li>');
				$('#folder_'+folders.current+' ul li').last().loaded = false;	// No data has been loaded about this folder
			}
			$('#folder_'+folders.current).toggleClass ('selected');	// Set the renamed folder as the selected folder
			folders.openClose(renamedFolder);		// Toggle the opened/closed status of the renamed folder (ie, open the folder, this will also display the files of the folder)
		}
	});
}

/**
 * This method is used to display all files in a folder
 */
Folders.prototype.showFiles = function () {
	if (this.current==-1)				// If no folder is selected we have nothing to display
		return;
	$.ajax ({
		url: 'includes/functions/fetchFiles.php',			// Use this script to get a list of files
		data: {'id': folders.current},	// Must provide the id of the folder to display
		type: 'post',
		success: function (data) {		// When the script has returned its data
			if (data.error) {			// An error occured
				alert (data.error);		// Display error message
				return;
			}
			$('#files .filelist').empty ();			// Empty the list of files
			for (var i=0; i<data.length; i++) {		// Go through all files to list
				// Add each file as a new line in the filelist
				var tmp = '<nobr><input type="checkbox" value="'+data[i].id+'" title="Klikk her og velg så endre navn/beskrivelse eller slette filen fra Filer menyen"/><a href="javascript:folders.fileClick('+data[i].id+');" title="'+data[i].description+'"><span class="name">'+data[i].name+'</span><span class="date">'+data[i].date+'</span><span class="type">'+data[i].mime+'</span><span class="size">'+data[i].size+'</span></a></nobr><br/>';
				$('#files .filelist').append (tmp);
			}
		}
	});
}

/**
 * Method used to rename a file
 *
 * @param id the id of the file to rename
 * @param name the new name of the file
 */
Folders.prototype.renameFile = function (id, name) {
	$.ajax ({
		url: 'includes/functions/renameFile.php',			// The script used to rename files
		data: {'id': id, 'name': name},	// Must provide the id and new name for the file
		type: 'post',
		success: function (tmp) {		// When we return
			folders.showFiles();		// Display the files (with the new name)
		}
	});
}

/**
 * Method used to change the description of a file
 *
 * @param id the id of the file to rename
 * @param descr the new description for the file
 */
Folders.prototype.changeFileDescr = function (id, descr) {
	$.ajax ({
		url: 'includes/functions/changeFileDescr.php',			// The script used to change the description of the file
		data: {'id': id, 'descr': descr},	// The id and new description of the file
		type: 'post',
		success: function (tmp) {			// When we return, display all files in the folder
			folders.showFiles();
		}
	});
}
/** 
 * Method used to remove a file
 * 
 * @param id the id of the file to remove
 */
Folders.prototype.removeFile = function (id) {
	$.ajax ({
		url: 'includes/functions/removeFile.php',				// Script used to delete a file form the database
		data: {'id': id},					// The id of the file to remove
		type: 'post',
		success: function (tmp) {			// When the script returns
			folders.showFiles();			// Display the files (less the removed file)
		}
	});
}